from django.core.exceptions import ValidationError
from django.utils import timezone
from django.db import transaction
from django.db.models import Count, Sum, Avg
from datetime import datetime, timedelta, time
from decimal import Decimal
import traceback
from app.models import User, MerchantInfo, OrderItem
from app.models import Employee, Attendance, EmployeeActivity, LeaveRequest, PerformanceRecord, SalaryRecord
from middleware.util import make_response
import logging
# 添加这一行来定义 logger
logger = logging.getLogger(__name__)

class EmployeeService:
    @staticmethod
    def create_employee(user_id, merchant_id, real_name, hire_date, work_start_time, work_end_time,
                        base_daily_salary, work_schedule=None, **salary_params):
        """
        创建员工档案
        :param user_id: 用户ID
        :param merchant_id: 商家ID
        :param real_name: 真实姓名
        :param hire_date: 入职日期
        :param work_start_time: 标准上班时间
        :param work_end_time: 标准下班时间
        :param base_daily_salary: 基础日薪
        :param work_schedule: 工作安排字典 {'monday': True, 'tuesday': True, ...}
        :param salary_params: 薪资相关参数
        :return: 创建结果
        """
        try:
            with transaction.atomic():
                # 1. 验证用户存在且角色正确
                user = User.objects.get(id=user_id)
                if hasattr(user, 'employee_profile'):
                    raise ValidationError("该用户已是员工")

                # 2. 验证商家存在
                merchant = MerchantInfo.objects.get(merchant_id=merchant_id)

                # 3. 设置默认工作安排（周一到周五上班）
                if not work_schedule:
                    work_schedule = {
                        'monday': True, 'tuesday': True, 'wednesday': True,
                        'thursday': True, 'friday': True, 'saturday': False, 'sunday': False
                    }

                # 4. 创建员工档案
                employee = Employee.objects.create(
                    user=user,
                    merchant=merchant,
                    real_name=real_name,
                    hire_date=hire_date,
                    work_start_time=work_start_time,
                    work_end_time=work_end_time,
                    base_daily_salary=base_daily_salary,
                    monday_work=work_schedule.get('monday', True),
                    tuesday_work=work_schedule.get('tuesday', True),
                    wednesday_work=work_schedule.get('wednesday', True),
                    thursday_work=work_schedule.get('thursday', True),
                    friday_work=work_schedule.get('friday', True),
                    saturday_work=work_schedule.get('saturday', False),
                    sunday_work=work_schedule.get('sunday', False),
                    late_penalty_per_minute=salary_params.get('late_penalty_per_minute', 0),
                    early_leave_penalty_per_minute=salary_params.get('early_leave_penalty_per_minute', 0),
                    activity_bonus_per_count=salary_params.get('activity_bonus_per_count', 0),
                )

            return make_response(
                code=201,
                message="员工创建成功",
                data={
                    "user_id": str(user.id),  # 直接返回user_id
                    "real_name": employee.real_name,
                    "username": user.username
                }
            )

        except User.DoesNotExist:
            raise ValidationError("用户不存在")
        except MerchantInfo.DoesNotExist:
            raise ValidationError("商家不存在")
        except Exception as e:
            raise ValidationError(f"创建员工失败：{str(e)}")



    @staticmethod
    def create_employee_by_username(username, merchant_id, real_name, hire_date, work_start_time, work_end_time,
                                  base_daily_salary, work_schedule=None, **salary_params):
        """
        通过用户名创建员工档案（更友好的接口）
        :param username: 用户名
        :param merchant_id: 商家ID
        :param real_name: 真实姓名
        :param hire_date: 入职日期
        :param work_start_time: 标准上班时间
        :param work_end_time: 标准下班时间
        :param base_daily_salary: 基础日薪
        :param work_schedule: 工作安排字典 {'monday': True, 'tuesday': True, ...}
        :param salary_params: 薪资相关参数
        :return: 创建结果
        """
        try:
            with transaction.atomic():
                # 1. 通过用户名查找用户
                try:
                    user = User.objects.get(username=username)
                except User.DoesNotExist:
                    raise ValidationError(f"用户名 '{username}' 不存在")

                # 2. 验证用户是否已是员工
                if hasattr(user, 'employee_profile'):
                    raise ValidationError(f"用户 '{username}' 已是员工")

                # 3. 验证商家存在
                try:
                    merchant = MerchantInfo.objects.get(merchant_id=merchant_id)
                except MerchantInfo.DoesNotExist:
                    raise ValidationError("商家不存在")

                # 4. 检查是否已在其他商家工作
                existing_employment = Employee.objects.filter(
                    user=user, 
                    employment_status='active'
                ).exclude(merchant_id=merchant_id).first()
                
                if existing_employment:
                    raise ValidationError(f"用户 '{username}' 已在商家 '{existing_employment.merchant.shop_name}' 工作")

                # 5. 设置默认工作安排（周一到周五上班）
                if not work_schedule:
                    work_schedule = {
                        'monday': True, 'tuesday': True, 'wednesday': True,
                        'thursday': True, 'friday': True, 'saturday': False, 'sunday': False
                    }

                # 6. 验证工作时间合理性
                if work_start_time >= work_end_time:
                    raise ValidationError("上班时间不能晚于或等于下班时间")

                # 7. 验证薪资参数
                if base_daily_salary <= 0:
                    raise ValidationError("基础日薪必须大于0")

                # 8. 创建员工档案
                employee = Employee.objects.create(
                    user=user,
                    merchant=merchant,
                    real_name=real_name,
                    hire_date=hire_date,
                    work_start_time=work_start_time,
                    work_end_time=work_end_time,
                    base_daily_salary=base_daily_salary,
                    monday_work=work_schedule.get('monday', True),
                    tuesday_work=work_schedule.get('tuesday', True),
                    wednesday_work=work_schedule.get('wednesday', True),
                    thursday_work=work_schedule.get('thursday', True),
                    friday_work=work_schedule.get('friday', True),
                    saturday_work=work_schedule.get('saturday', False),
                    sunday_work=work_schedule.get('sunday', False),
                    late_penalty_per_minute=salary_params.get('late_penalty_per_minute', 0),
                    early_leave_penalty_per_minute=salary_params.get('early_leave_penalty_per_minute', 0),
                    activity_bonus_per_count=salary_params.get('activity_bonus_per_count', 0),
                )

                # 9. 记录操作日志
                logger.info(f"新员工创建成功: username={username}, real_name={real_name}, merchant={merchant.shop_name}")

            return make_response(
                code=201,
                message="员工创建成功",
                data={
                    "user_id": str(user.id),
                    "username": user.username,
                    "real_name": employee.real_name,
                    "merchant_name": merchant.shop_name,
                    "hire_date": hire_date.isoformat(),
                    "employment_status": employee.get_employment_status_display(),
                    "base_daily_salary": float(employee.base_daily_salary)
                }
            )

        except ValidationError:
            raise
        except Exception as e:
            logger.error(f"创建员工失败: username={username}, error={str(e)}")
            raise ValidationError(f"创建员工失败：{str(e)}")

            
    @staticmethod
    def update_employee_info(user_id, **kwargs):
        """
        更新员工基本信息
        :param user_id: 用户ID
        :param kwargs: 更新字段
        :return: 更新结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id)

                # 更新允许修改的字段
                updatable_fields = [
                    'real_name', 'work_start_time', 'work_end_time', 'base_daily_salary',
                    'monday_work', 'tuesday_work', 'wednesday_work', 'thursday_work',
                    'friday_work', 'saturday_work', 'sunday_work',
                    'late_penalty_per_minute', 'early_leave_penalty_per_minute', 'activity_bonus_per_count','employment_status'
                ]

                for field, value in kwargs.items():
                    if field in updatable_fields and value is not None:
                        setattr(employee, field, value)

                        # 根据更新的状态返回不同的消息
                if 'employment_status' in kwargs:
                    if kwargs['employment_status'] == 'resigned':
                        message = "员工已设置为离职状态"
                    elif kwargs['employment_status'] == 'active':
                        message = "员工已恢复为在职状态"
                    else:
                        message = "员工信息更新成功"
                else:
                    message = "员工信息更新成功"

                employee.full_clean()
                employee.save()

            return make_response(
                code=200,
                message="员工信息更新成功",
                data={"user_id": str(employee.user.id)}
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在或已离职")
        except Exception as e:
            raise ValidationError(f"更新失败：{str(e)}")

    @staticmethod
    def get_employee_list(merchant_id, employment_status=None):
        """
        获取商家员工列表
        :param merchant_id: 商家ID
        :param employment_status: 在职状态
        :return: 员工列表
        """
        try:
            queryset = Employee.objects.filter(merchant_id=merchant_id).select_related('user')
        
            # 如果指定了状态，则按状态过滤；否则返回所有员工
            if employment_status:
                queryset = queryset.filter(employment_status=employment_status)
            
            employees = queryset.order_by('-hire_date')

            result = []
            for emp in employees:
                employee_data = {
                    "user_id": str(emp.user.id),
                    "real_name": emp.real_name,
                    "username": emp.user.username,
                    "phone": emp.user.phone,
                    "hire_date": emp.hire_date.isoformat(),
                    "work_time": f"{emp.work_start_time} - {emp.work_end_time}",
                    "base_daily_salary": float(emp.base_daily_salary),
                    "employment_status": emp.get_employment_status_display(),
                    
                    # 添加绩效相关信息
                    "salary_config": {
                        "late_penalty_per_minute": float(emp.late_penalty_per_minute),
                        "early_leave_penalty_per_minute": float(emp.early_leave_penalty_per_minute),
                        "activity_bonus_per_count": float(emp.activity_bonus_per_count)
                    },
                    
                    # 工作安排
                    "work_schedule": {
                        "monday": emp.monday_work,
                        "tuesday": emp.tuesday_work,
                        "wednesday": emp.wednesday_work,
                        "thursday": emp.thursday_work,
                        "friday": emp.friday_work,
                        "saturday": emp.saturday_work,
                        "sunday": emp.sunday_work
                    }
                }
                
                result.append(employee_data)

            return make_response(
                code=200,
                message="获取成功",
                data=result
            )

        except Exception as e:
            raise ValidationError(f"获取员工列表失败：{str(e)}")
import pytz
# 定义东八区时区
BEIJING_TZ = pytz.timezone('Asia/Shanghai')

def get_beijing_time():
    """获取当前北京时间"""
    return timezone.now().astimezone(BEIJING_TZ)

def get_beijing_date():
    """获取当前北京日期"""
    return get_beijing_time().date()

def get_beijing_time_only():
    """获取当前北京时间（只保留时间部分）"""
    return get_beijing_time().time()
class AttendanceService:
    @staticmethod
    def clock_in(user_id, actual_time=None):
        """
        员工打卡上班
        :param user_id: 用户ID
        :param actual_time: 实际打卡时间（可选，默认当前北京时间）
        :return: 打卡结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id, employment_status='active')
                
                # 使用北京时间
                today = get_beijing_date()
                actual_time = actual_time or get_beijing_time_only()

                # 检查今天是否应该上班
                weekday = today.weekday()  # 0=Monday, 6=Sunday
                work_days = [
                    employee.monday_work, employee.tuesday_work, employee.wednesday_work,
                    employee.thursday_work, employee.friday_work, employee.saturday_work, employee.sunday_work
                ]

                if not work_days[weekday]:
                    raise ValidationError("今天不是工作日")

                # 获取或创建考勤记录
                attendance, created = Attendance.objects.get_or_create(
                    employee=employee,
                    work_date=today,
                    defaults={
                        'scheduled_start': employee.work_start_time,
                        'scheduled_end': employee.work_end_time,
                    }
                )

                if attendance.actual_start:
                    raise ValidationError("今日已打卡上班")

                attendance.actual_start = actual_time
                attendance.save()

                # 记录日志
                logger.info(f"员工上班打卡成功: {employee.real_name}, 时间: {actual_time}, 日期: {today}")

            return make_response(
                code=200,
                message="上班打卡成功",
                data={
                    "employee_name": employee.real_name,
                    "clock_in_time": actual_time.strftime("%H:%M:%S"),
                    "scheduled_time": employee.work_start_time.strftime("%H:%M:%S"),
                    "date": today.isoformat(),
                    "timezone": "北京时间 (UTC+8)"
                }
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            logger.error(f"上班打卡失败: user_id={user_id}, error={str(e)}")
            raise ValidationError(f"打卡失败：{str(e)}")

    @staticmethod
    def clock_out(user_id, actual_time=None):
        """
        员工打卡下班
        :param user_id: 用户ID
        :param actual_time: 实际打卡时间（可选，默认当前北京时间）
        :return: 打卡结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id, employment_status='active')
                
                # 使用北京时间
                today = get_beijing_date()
                actual_time = actual_time or get_beijing_time_only()

                try:
                    attendance = Attendance.objects.get(employee=employee, work_date=today)
                except Attendance.DoesNotExist:
                    raise ValidationError("今日尚未打卡上班")

                if not attendance.actual_start:
                    raise ValidationError("今日尚未打卡上班")

                if attendance.actual_end:
                    raise ValidationError("今日已打卡下班")

                attendance.actual_end = actual_time
                attendance.save()

                # 记录日志
                logger.info(f"员工下班打卡成功: {employee.real_name}, 时间: {actual_time}, 日期: {today}")

                # 自动生成绩效记录
                PerformanceService.calculate_daily_performance(user_id, today)

            return make_response(
                code=200,
                message="下班打卡成功",
                data={
                    "employee_name": employee.real_name,
                    "clock_out_time": actual_time.strftime("%H:%M:%S"),
                    "scheduled_time": employee.work_end_time.strftime("%H:%M:%S"),
                    "date": today.isoformat(),
                    "timezone": "北京时间 (UTC+8)"
                }
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            logger.error(f"下班打卡失败: user_id={user_id}, error={str(e)}")
            raise ValidationError(f"打卡失败：{str(e)}")

    @staticmethod
    def get_attendance_records(user_id, start_date=None, end_date=None):
        """
        获取员工考勤记录
        :param user_id: 用户ID
        :param start_date: 开始日期
        :param end_date: 结束日期
        :return: 考勤记录列表
        """
        try:
            employee = Employee.objects.get(user_id=user_id)

            queryset = Attendance.objects.filter(employee=employee)

            if start_date:
                queryset = queryset.filter(work_date__gte=start_date)
            if end_date:
                queryset = queryset.filter(work_date__lte=end_date)

            records = queryset.order_by('-work_date')

            result = []
            for record in records:
                result.append({
                    "work_date": record.work_date.isoformat(),
                    "scheduled_start": record.scheduled_start.strftime("%H:%M:%S"),
                    "scheduled_end": record.scheduled_end.strftime("%H:%M:%S"),
                    "actual_start": record.actual_start.strftime("%H:%M:%S") if record.actual_start else None,
                    "actual_end": record.actual_end.strftime("%H:%M:%S") if record.actual_end else None,
                    "notes": record.notes
                })

            return make_response(
                code=200,
                message="获取成功",
                data=result
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            raise ValidationError(f"获取考勤记录失败：{str(e)}")


class EmployeeActivityService:
    @staticmethod
    def record_activity(user_id, order_id, dish_id, activity_type, activity_time=None):
        """
        记录员工活动
        :param user_id: 用户ID
        :param order_id: 订单ID
        :param dish_id: 菜品ID
        :param activity_type: 活动类型 ('serve_dish' 或 'cook_dish')
        :param activity_time: 活动时间（可选，默认当前时间）
        :return: 记录结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id, employment_status='active')
                order_item = OrderItem.objects.get(order_id=order_id, dish_id=dish_id)
                activity_time = activity_time or timezone.now()

                # 检查是否已记录过相同活动
                existing_activity = EmployeeActivity.objects.filter(
                    employee=employee,
                    order_item=order_item,
                    activity_type=activity_type
                ).first()

                if existing_activity:
                    raise ValidationError("该活动已记录")

                # 创建活动记录
                activity = EmployeeActivity.objects.create(
                    employee=employee,
                    order_item=order_item,
                    activity_type=activity_type,
                    activity_time=activity_time
                )

                # 更新订单项状态（根据活动类型）
                if activity_type == 'cook_dish':
                    order_item.status = 'completed'
                    order_item.completed_at = activity_time
                elif activity_type == 'serve_dish':
                    # 服务员上菜后可以标记为已完成
                    pass

                order_item.save()

            return make_response(
                code=201,
                message="活动记录成功",
                data={
                    "activity_id": str(activity.activity_id),
                    "employee_name": employee.real_name,
                    "activity_type": activity.get_activity_type_display(),
                    "dish_name": order_item.dish.dish_name if order_item.dish else "已删除菜品",
                    "activity_time": activity_time.isoformat(),
                    "order_id": str(order_item.order.order_id),
                    "dish_id": str(order_item.dish.dish_id) if order_item.dish else None
                }
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except OrderItem.DoesNotExist:
            raise ValidationError("订单项不存在")
        except Exception as e:
            raise ValidationError(f"记录活动失败：{str(e)}")

    @staticmethod
    def record_cook_activity(user_id, order_id, dish_id, activity_time=None):
        """
        记录厨师制作菜品活动
        :param user_id: 用户ID
        :param order_id: 订单ID
        :param dish_id: 菜品ID
        :param activity_time: 活动时间（可选，默认当前时间）
        :return: 记录结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id, employment_status='active')
                order_item = OrderItem.objects.get(order_id=order_id, dish_id=dish_id)
                activity_time = activity_time or get_beijing_time()
                # 检查订单项状态
                if order_item.status != 'in_preparation':
                    raise ValidationError("该订单项不在制作状态")

                # # 检查是否已开始制作
                # if order_item.started_at is not None:
                #     raise ValidationError("该菜品已开始制作")

                # 检查是否已记录过制作活动
                existing_activity = order_item.employee_activities.filter(
                    employee=employee,
                    activity_type='cook_dish'
                ).first()

                if existing_activity:
                    raise ValidationError("该制作活动已记录")

                # 创建活动记录
                from app.models import EmployeeActivity
                activity = EmployeeActivity.objects.create(
                    employee=employee,
                    order_item=order_item,
                    activity_type='cook_dish',
                    activity_time=activity_time
                )

                # 更新订单项状态 - 标记为已开始制作并完成
                order_item.started_at = activity_time
                order_item.completed_at = activity_time
                order_item.status = 'cooked'
                order_item.save()

                return make_response(
                    code=201,
                    message="制作活动记录成功",
                    data={
                        "activity_id": str(activity.activity_id),
                        "employee_name": employee.real_name,
                        "dish_name": order_item.dish.dish_name if order_item.dish else "已删除菜品",
                        "activity_time": activity_time.isoformat(),
                        "order_id": str(order_item.order.order_id),
                        "table_number": order_item.order.table_number,
                        "status": "已完成制作，等待上菜"
                    }
                )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except OrderItem.DoesNotExist:
            raise ValidationError("订单项不存在")
        except Exception as e:
            traceback.print_exc()
            logger.error(f"记录上菜活动失败: user_id={user_id}, error={str(e)}")
            logger.error(traceback.format_exc())  # 也可以用 format_exc() 获取字符串形式
            logger.error(f"记录制作活动失败: user_id={user_id}, order_id={order_id}, dish_id={dish_id}, error={str(e)}")
            raise ValidationError(f"记录制作活动失败：{str(e)}")

    @staticmethod
    def record_serve_activity(user_id, order_id, dish_id, activity_time=None):
        """
        记录服务员上菜活动
        :param user_id: 用户ID
        :param order_id: 订单ID
        :param dish_id: 菜品ID
        :param activity_time: 活动时间（可选，默认当前时间）
        :return: 记录结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id, employment_status='active')
                order_item = OrderItem.objects.get(order_id=order_id, dish_id=dish_id)
                activity_time = activity_time or get_beijing_time()

                # 检查订单项状态
                if order_item.status != 'cooked':
                    raise ValidationError("该订单项不在待上菜状态")

                # 检查是否已完成制作
                if order_item.completed_at is None:
                    raise ValidationError("该菜品尚未完成制作")

                # 检查是否已记录过上菜活动
                existing_activity = order_item.employee_activities.filter(
                    activity_type='serve_dish'
                ).first()

                if existing_activity:
                    raise ValidationError("该上菜活动已记录")

                # 创建活动记录
                from app.models import EmployeeActivity
                activity = EmployeeActivity.objects.create(
                    employee=employee,
                    order_item=order_item,
                    activity_type='serve_dish',
                    activity_time=activity_time
                )

                # 更新订单项状态 - 标记为已完成
                order_item.status = 'completed'
                order_item.save()

                # 检查整个订单是否都已完成
                order = order_item.order
                remaining_items = order.items.exclude(status='completed').count()
                if remaining_items == 0:
                    order.status = 'completed'
                    order.save()

                return make_response(
                    code=201,
                    message="上菜活动记录成功",
                    data={
                        "activity_id": str(activity.activity_id),
                        "employee_name": employee.real_name,
                        "dish_name": order_item.dish.dish_name if order_item.dish else "已删除菜品",
                        "activity_time": activity_time.isoformat(),
                        "order_id": str(order_item.order.order_id),
                        "table_number": order_item.order.table_number,
                        "status": "已完成上菜",
                        "order_completed": remaining_items == 0
                    }
                )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except OrderItem.DoesNotExist:
            raise ValidationError("订单项不存在")
        except Exception as e:
            traceback.print_exc()
            logger.error(f"记录上菜活动失败: user_id={user_id}, error={str(e)}")
            logger.error(traceback.format_exc())  # 也可以用 format_exc() 获取字符串形式
            logger.error(f"记录上菜活动失败: user_id={user_id}, order_id={order_id}, dish_id={dish_id}, error={str(e)}")
            raise ValidationError(f"记录上菜活动失败：{str(e)}")

    @staticmethod
    def get_employee_activities(user_id, date=None, activity_type=None):
        """
        获取员工活动记录
        :param user_id: 用户ID
        :param date: 指定日期（可选）
        :param activity_type: 活动类型（可选）
        :return: 活动记录列表
        """
        try:
            employee = Employee.objects.get(user_id=user_id)

            queryset = EmployeeActivity.objects.filter(employee=employee).select_related('order_item__dish')

            if date:
                queryset = queryset.filter(activity_time__date=date)
            if activity_type:
                queryset = queryset.filter(activity_type=activity_type)

            activities = queryset.order_by('-activity_time')

            result = []
            for activity in activities:
                result.append({
                    "activity_id": str(activity.activity_id),
                    "activity_type": activity.get_activity_type_display(),
                    "dish_name": activity.order_item.dish.dish_name if activity.order_item.dish else "已删除菜品",
                    "activity_time": activity.activity_time.isoformat(),
                    "order_id": str(activity.order_item.order.order_id)
                })

            return make_response(
                code=200,
                message="获取成功",
                data=result
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            raise ValidationError(f"获取活动记录失败：{str(e)}")


class LeaveRequestService:
    @staticmethod
    def submit_leave_request(user_id, leave_type, start_date, end_date, reason):
        """
        提交请假申请
        :param user_id: 用户ID
        :param leave_type: 请假类型
        :param start_date: 开始日期
        :param end_date: 结束日期
        :param reason: 请假原因
        :return: 申请结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id, employment_status='active')

                # 验证日期合理性
                if start_date > end_date:
                    raise ValidationError("开始日期不能晚于结束日期")

                if start_date < timezone.now().date():
                    raise ValidationError("不能申请过去的日期")

                # 检查是否有重叠的请假申请
                overlapping_requests = LeaveRequest.objects.filter(
                    employee=employee,
                    status__in=['pending', 'approved'],
                    start_date__lte=end_date,
                    end_date__gte=start_date
                )

                if overlapping_requests.exists():
                    raise ValidationError("该时间段已有请假申请")

                # 创建请假申请
                leave_request = LeaveRequest.objects.create(
                    employee=employee,
                    leave_type=leave_type,
                    start_date=start_date,
                    end_date=end_date,
                    reason=reason
                )

            return make_response(
                code=201,
                message="请假申请提交成功",
                data={
                    "leave_id": str(leave_request.leave_id),
                    "leave_type": leave_request.get_leave_type_display(),
                    "start_date": start_date.isoformat(),
                    "end_date": end_date.isoformat(),
                    "status": leave_request.get_status_display()
                }
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            raise ValidationError(f"提交请假申请失败：{str(e)}")

    @staticmethod
    def approve_leave_request(leave_id, merchant_user_id, approval_notes=None):
        """
        批准请假申请（简化版本）
        :param leave_id: 请假申请ID
        :param merchant_user_id: 商家用户ID
        :param approval_notes: 审批备注
        :return: 审批结果
        """
        try:
            with transaction.atomic():
                # 1. 获取请假申请
                leave_request = LeaveRequest.objects.get(leave_id=leave_id)
                
                # 2. 验证商家身份和权限
                try:
                    merchant_user = User.objects.get(id=merchant_user_id, role='merchant')
                    merchant_info = MerchantInfo.objects.get(merchant_id=merchant_user_id)
                except (User.DoesNotExist, MerchantInfo.DoesNotExist):
                    raise ValidationError("无效的商家用户")

                # 3. 验证请假申请是否属于该商家的员工
                if leave_request.employee.merchant_id != merchant_info.merchant_id:
                    raise ValidationError("无权审批其他商家员工的请假申请")

                # 4. 检查申请状态
                if leave_request.status != 'pending':
                    raise ValidationError("该请假申请已处理")

                # 5. 更新申请状态（不记录审批人信息）
                leave_request.status = 'approved'
                leave_request.approval_time = timezone.now()
                leave_request.approval_notes = approval_notes
                leave_request.save()

                # 6. 记录日志
                logger.info(f"请假申请已批准: leave_id={leave_id}, merchant={merchant_info.shop_name}, employee={leave_request.employee.real_name}")

            return make_response(
                code=200,
                message="请假申请批准成功",
                data={
                    "leave_id": str(leave_request.leave_id),
                    "employee_name": leave_request.employee.real_name,
                    "approval_time": leave_request.approval_time.isoformat(),
                    "approval_notes": leave_request.approval_notes
                }
            )

        except LeaveRequest.DoesNotExist:
            raise ValidationError("请假申请不存在")
        except Exception as e:
            logger.error(f"审批失败: leave_id={leave_id}, merchant_user_id={merchant_user_id}, error={str(e)}")
            raise ValidationError(f"审批失败：{str(e)}")

    @staticmethod
    def reject_leave_request(leave_id, merchant_user_id, approval_notes):
        """
        拒绝请假申请（简化版本）
        :param leave_id: 请假申请ID
        :param merchant_user_id: 商家用户ID
        :param approval_notes: 拒绝原因
        :return: 审批结果
        """
        try:
            with transaction.atomic():
                # 1. 获取请假申请
                leave_request = LeaveRequest.objects.get(leave_id=leave_id)
                
                # 2. 验证商家身份和权限
                try:
                    merchant_user = User.objects.get(id=merchant_user_id, role='merchant')
                    merchant_info = MerchantInfo.objects.get(merchant_id=merchant_user_id)
                except (User.DoesNotExist, MerchantInfo.DoesNotExist):
                    raise ValidationError("无效的商家用户")

                # 3. 验证请假申请是否属于该商家的员工
                if leave_request.employee.merchant_id != merchant_info.merchant_id:
                    raise ValidationError("无权审批其他商家员工的请假申请")

                # 4. 检查申请状态
                if leave_request.status != 'pending':
                    raise ValidationError("该请假申请已处理")

                # 5. 验证拒绝原因
                if not approval_notes or approval_notes.strip() == "":
                    raise ValidationError("拒绝请假必须提供原因")

                # 6. 更新申请状态（不记录审批人信息）
                leave_request.status = 'rejected'
                leave_request.approval_time = timezone.now()
                leave_request.approval_notes = approval_notes
                leave_request.save()

                # 7. 记录日志
                logger.info(f"请假申请已拒绝: leave_id={leave_id}, merchant={merchant_info.shop_name}, employee={leave_request.employee.real_name}")

            return make_response(
                code=200,
                message="请假申请已拒绝",
                data={
                    "leave_id": str(leave_request.leave_id),
                    "employee_name": leave_request.employee.real_name,
                    "rejection_reason": approval_notes,
                    "approval_time": leave_request.approval_time.isoformat()
                }
            )

        except LeaveRequest.DoesNotExist:
            raise ValidationError("请假申请不存在")
        except Exception as e:
            logger.error(f"拒绝审批失败: leave_id={leave_id}, merchant_user_id={merchant_user_id}, error={str(e)}")
            raise ValidationError(f"审批失败：{str(e)}")

    @staticmethod
    def get_leave_requests(user_id=None, merchant_id=None, status=None):
        """
        获取请假申请列表
        :param user_id: 用户ID（可选，获取特定员工的申请）
        :param merchant_id: 商家ID（可选，获取商家所有员工的申请）
        :param status: 申请状态（可选）
        :return: 请假申请列表
        """
        try:
            queryset = LeaveRequest.objects.select_related('employee')

            if user_id:
                queryset = queryset.filter(employee__user_id=user_id)
            elif merchant_id:
                queryset = queryset.filter(employee__merchant_id=merchant_id)

            if status:
                queryset = queryset.filter(status=status)

            requests = queryset.order_by('-created_at')

            result = []
            for req in requests:
                result.append({
                    "leave_id": str(req.leave_id),
                    "employee_name": req.employee.real_name,
                    "leave_type": req.get_leave_type_display(),
                    "start_date": req.start_date.isoformat(),
                    "end_date": req.end_date.isoformat(),
                    "reason": req.reason,
                    "status": req.get_status_display(),
                    "created_at": req.created_at.isoformat(),
                    "approval_time": req.approval_time.isoformat() if req.approval_time else None,
                    "approval_notes": req.approval_notes
                })

            return make_response(
                code=200,
                message="获取成功",
                data=result
            )

        except Exception as e:
            raise ValidationError(f"获取请假申请失败：{str(e)}")


class PerformanceService:
    @staticmethod
    def calculate_daily_performance(user_id, record_date):
        """
        计算员工每日绩效和工资
        :param user_id: 用户ID (修改：原来是employee_id)
        :param record_date: 记录日期
        :return: 绩效计算结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id)

                # 检查是否应该上班
                weekday = record_date.weekday()
                work_days = [
                    employee.monday_work, employee.tuesday_work, employee.wednesday_work,
                    employee.thursday_work, employee.friday_work, employee.saturday_work, employee.sunday_work
                ]
                is_work_day = work_days[weekday]

                # 获取考勤记录
                try:
                    attendance = Attendance.objects.get(employee=employee, work_date=record_date)
                except Attendance.DoesNotExist:
                    attendance = None

                # 检查请假状态 - 确保当天在已批准的请假期间内
                is_on_leave = LeaveRequest.objects.filter(
                    employee=employee,
                    status='approved',
                    start_date__lte=record_date,
                    end_date__gte=record_date
                ).exists()
                
                # 修复：确保 is_present 始终是布尔值
                is_present = bool(attendance and attendance.actual_start is not None and attendance.actual_end is not None)

                # 计算考勤时间
                late_minutes = 0
                early_leave_minutes = 0
                overtime_minutes = 0
                work_minutes = 0

                if attendance and attendance.actual_start is not None and attendance.actual_end is not None:
                    # 计算迟到时间
                    if attendance.actual_start > attendance.scheduled_start:
                        late_delta = datetime.combine(record_date, attendance.actual_start) - \
                                    datetime.combine(record_date, attendance.scheduled_start)
                        late_minutes = int(late_delta.total_seconds() / 60)

                    # 计算早退时间
                    if attendance.actual_end < attendance.scheduled_end:
                        early_delta = datetime.combine(record_date, attendance.scheduled_end) - \
                                    datetime.combine(record_date, attendance.actual_end)
                        early_leave_minutes = int(early_delta.total_seconds() / 60)

                    # 计算加班时间
                    if attendance.actual_end > attendance.scheduled_end:
                        overtime_delta = datetime.combine(record_date, attendance.actual_end) - \
                                        datetime.combine(record_date, attendance.scheduled_end)
                        overtime_minutes = int(overtime_delta.total_seconds() / 60)

                    # 计算实际工作时间
                    work_delta = datetime.combine(record_date, attendance.actual_end) - \
                                datetime.combine(record_date, attendance.actual_start)
                    work_minutes = int(work_delta.total_seconds() / 60)

                # 获取当日活动次数
                activity_count = EmployeeActivity.objects.filter(
                    employee=employee,
                    activity_time__date=record_date
                ).count()

                # 计算工资
                base_salary = employee.base_daily_salary if (is_work_day and (is_present or is_on_leave)) else Decimal('0')
                late_penalty = Decimal(str(late_minutes)) * employee.late_penalty_per_minute
                early_leave_penalty = Decimal(str(early_leave_minutes)) * employee.early_leave_penalty_per_minute
                activity_bonus = Decimal(str(activity_count)) * employee.activity_bonus_per_count
                overtime_bonus = (Decimal(str(overtime_minutes)) / Decimal('60')) * (employee.base_daily_salary / Decimal('8'))  # 按小时计算加班费

                daily_total_salary = base_salary - late_penalty - early_leave_penalty + activity_bonus + overtime_bonus

                # 创建或更新绩效记录
                performance, created = PerformanceRecord.objects.update_or_create(
                    employee=employee,
                    record_date=record_date,
                    defaults={
                        'is_work_day': bool(is_work_day),  # 确保是布尔值
                        'is_present': is_present,
                        'is_on_leave': bool(is_on_leave),  # 确保是布尔值
                        'late_minutes': late_minutes,
                        'early_leave_minutes': early_leave_minutes,
                        'overtime_minutes': overtime_minutes,
                        'work_minutes': work_minutes,
                        'activity_count': activity_count,
                        'base_salary': base_salary,
                        'late_penalty': late_penalty,
                        'early_leave_penalty': early_leave_penalty,
                        'activity_bonus': activity_bonus,
                        'overtime_bonus': overtime_bonus,
                        'daily_total_salary': daily_total_salary,
                    }
                )

            return make_response(
                code=200,
                message="绩效计算完成",
                data={
                    "employee_name": employee.real_name,
                    "record_date": record_date.isoformat(),
                    "daily_total_salary": float(daily_total_salary),
                    "is_present": is_present,
                    "is_on_leave": is_on_leave,
                    "activity_count": activity_count
                }
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            traceback.print_exc()
            raise ValidationError(f"绩效计算失败：{str(e)}")

    @staticmethod
    def get_performance_records(user_id, start_date=None, end_date=None):
        """
        获取员工绩效记录
        :param user_id: 用户ID (修改：原来是employee_id)
        :param start_date: 开始日期
        :param end_date: 结束日期
        :return: 绩效记录列表
        """
        try:
            employee = Employee.objects.get(user_id=user_id)

            queryset = PerformanceRecord.objects.filter(employee=employee)

            if start_date:
                queryset = queryset.filter(record_date__gte=start_date)
            if end_date:
                queryset = queryset.filter(record_date__lte=end_date)

            records = queryset.order_by('-record_date')

            result = []
            for record in records:
                result.append({
                    "record_date": record.record_date.isoformat(),
                    "is_work_day": record.is_work_day,
                    "is_present": record.is_present,
                    "is_on_leave": record.is_on_leave,
                    "late_minutes": record.late_minutes,
                    "early_leave_minutes": record.early_leave_minutes,
                    "overtime_minutes": record.overtime_minutes,
                    "work_minutes": record.work_minutes,
                    "activity_count": record.activity_count,
                    "base_salary": float(record.base_salary),
                    "late_penalty": float(record.late_penalty),
                    "early_leave_penalty": float(record.early_leave_penalty),
                    "activity_bonus": float(record.activity_bonus),
                    "overtime_bonus": float(record.overtime_bonus),
                    "daily_total_salary": float(record.daily_total_salary)
                })

            return make_response(
                code=200,
                message="获取成功",
                data=result
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            raise ValidationError(f"获取绩效记录失败：{str(e)}")


class SalaryService:
    @staticmethod
    def calculate_salary(user_id, start_date, end_date):
        """
        计算员工指定时间段工资
        :param user_id: 用户ID
        :param start_date: 开始日期
        :param end_date: 结束日期
        :return: 工资计算结果
        """
        try:
            with transaction.atomic():
                employee = Employee.objects.get(user_id=user_id)

                # 获取时间段内的绩效记录
                performance_records = PerformanceRecord.objects.filter(
                    employee=employee,
                    record_date__gte=start_date,
                    record_date__lte=end_date
                )

                if not performance_records.exists():
                    raise ValidationError("该时间段内无绩效记录")

                # 计算总工资
                total_salary = performance_records.aggregate(
                    total=Sum('daily_total_salary')
                )['total'] or 0

                # 创建工资记录
                salary_record, created = SalaryRecord.objects.update_or_create(
                    employee=employee,
                    start_date=start_date,
                    end_date=end_date,
                    defaults={
                        'total_salary': total_salary
                    }
                )

            return make_response(
                code=201 if created else 200,
                message="工资计算完成",
                data={
                    "salary_id": str(salary_record.salary_id),
                    "employee_name": employee.real_name,
                    "start_date": start_date.isoformat(),
                    "end_date": end_date.isoformat(),
                    "total_salary": float(total_salary),
                    "days_count": performance_records.count()
                }
            )

        except Employee.DoesNotExist:
            raise ValidationError("员工不存在")
        except Exception as e:
            raise ValidationError(f"工资计算失败：{str(e)}")

    @staticmethod
    def get_salary_records(user_id=None, merchant_id=None):
        """
        获取工资记录
        :param user_id: 用户ID（可选）
        :param merchant_id: 商家ID（可选）
        :return: 工资记录列表
        """
        try:
            queryset = SalaryRecord.objects.select_related('employee')

            if user_id:
                queryset = queryset.filter(employee__user_id=user_id)
            elif merchant_id:
                queryset = queryset.filter(employee__merchant_id=merchant_id)

            records = queryset.order_by('-start_date')

            result = []
            for record in records:
                result.append({
                    "salary_id": str(record.salary_id),
                    "employee_name": record.employee.real_name,
                    "start_date": record.start_date.isoformat(),
                    "end_date": record.end_date.isoformat(),
                    "total_salary": float(record.total_salary),
                    "created_at": record.created_at.isoformat()
                })

            return make_response(
                code=200,
                message="获取成功",
                data=result
            )

        except Exception as e:
            raise ValidationError(f"获取工资记录失败：{str(e)}")